Constructing arguments of system commands from user input is security-sensitive. It has led in the past to the following vulnerabilities:
Arguments of system commands are processed by the executed program. The arguments are usually used to configure and influence the behavior of the
programs. Control over a single argument might be enough for an attacker to trigger dangerous features like executing arbitrary commands or writing
files into specific directories.
Ask Yourself Whether
- Malicious arguments can result in undesired behavior in the executed command.
- Passing user input to a system command is not necessary.
There is a risk if you answered yes to any of those questions.
Recommended Secure Coding Practices
- Avoid constructing system commands from user input when possible.
- Ensure that no risky arguments can be injected for the given program, e.g., type-cast the argument to an integer.
- Use a more secure interface to communicate with other programs, e.g., the standard input stream (stdin).
Sensitive Code Example
Arguments like -delete
or -exec
for the find
command can alter the expected behavior and result in
vulnerabilities:
const { spawn } = require("child_process");
const input = req.query.input;
const proc = spawn("/usr/bin/find", [input]); // Sensitive
Compliant Solution
Use an allow-list to restrict the arguments to trusted values:
const { spawn } = require("child_process");
const input = req.query.input;
if (allowed.includes(input)) {
const proc = spawn("/usr/bin/find", [input]);
}
See